package com.jason.www.widget.dialogfragment;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import com.jason.www.R;
import java.lang.reflect.Field;
import java.util.Objects;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDialogFragment;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * @author：Jason
 * @date：2020/9/7 12:24
 * @email：1129847330@qq.com
 * @description:
 */
public abstract class BaseDialogFragment extends AppCompatDialogFragment {
    protected FragmentActivity mActivity;
    protected Context mContext;
    private Unbinder unbinder;

    @Override
    public void show(@NonNull FragmentManager manager, @Nullable String tag) {
        if (!isAdded()) {
            boolean canProcess = true;
            try {
                Class c = Class.forName("androidx.fragment.app.DialogFragment");
                Object obj = this;
                Field dismissed = c.getDeclaredField("mDismissed");
                dismissed.setAccessible(true);
                dismissed.set(obj, false);
                Field shownByMe = c.getDeclaredField("mShownByMe");
                shownByMe.setAccessible(true);
                shownByMe.set(obj, true);
            } catch (Exception e) {
                e.printStackTrace();
                canProcess = false;
            } finally {
                if (canProcess) {
                    FragmentTransaction ft = manager.beginTransaction();
                    ft.add(this, tag);
                    ft.commitAllowingStateLoss();
                    Log.d("BaseDialogFragment", "show commitAllowingStateLoss");
                } else {
                    super.show(manager, tag);
                    Log.d("BaseDialogFragment", "show commit");
                }
            }
        } else {
            super.show(manager, tag);
        }
    }

    public void show(FragmentActivity activity, String tag) {
        mActivity = activity;
        mContext = activity;
        show(activity.getSupportFragmentManager(), tag);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogTheme);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        return super.onCreateDialog(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(getLayoutRes(), container, false);
        unbinder = ButterKnife.bind(this, view);
        initView(view);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData();
        initEvent();
    }

    protected void initView(View view) {
    }

    protected void initData() {

    }

    protected void initEvent() {

    }

    protected abstract int getLayoutRes();

    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            Window window = dialog.getWindow();
            WindowManager.LayoutParams lp = Objects.requireNonNull(window).getAttributes();
            lp.width = getWidth();
            lp.height = getHeight();
            lp.gravity = getGravity();
            lp.windowAnimations = getAnimation();
            window.setAttributes(lp);
        }
    }

    public int getWidth() {
        return ViewGroup.LayoutParams.MATCH_PARENT;
    }

    public int getHeight() {
        return ViewGroup.LayoutParams.WRAP_CONTENT;
    }

    public int getGravity() {
        return Gravity.BOTTOM;
    }

    public int getAnimation() {
        return R.style.DialogAnimation;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (unbinder != null) {
            unbinder.unbind();
        }
    }
}